import { isFunction } from "@/utils/is";
import dayjs from "dayjs";
import { computed, reactive, ref, toRefs, watch } from "vue";

function getDefaultFormat(mode = "date") {
  switch (mode) {
    case "date":
      return "YYYY-MM-DD";
    case "month":
      return "YYYY-MM";
    case "year":
      return "YYYY";
    case "week":
      return "gggg-wo";
    case "quarter":
      return "YYYY-[Q]Q";
    default:
      return "YYYY-MM-DD";
  }
}

function getDefaultValueFormat(mode = "date") {
  switch (mode) {
    case "date":
      return "YYYY-MM-DD";
    case "month":
      return "YYYY-MM";
    case "year":
      return "YYYY";
    case "week":
      return "YYYY-MM-DD";
    case "quarter":
      return "YYYY-MM";
    default:
      return "YYYY-MM-DD";
  }
}

export function useFormat(props) {
  const {
    format: propFormat,
    mode,
    valueFormat: propValueFormat,
  } = toRefs(props);
  const format = computed(
    () =>
      (!isFunction(propFormat.value == null ? void 0 : propFormat.value) &&
        (propFormat.value == null ? void 0 : propFormat.value)) ||
      getDefaultFormat(mode.value == null ? void 0 : mode.value),
  );
  const valueFormat = computed(
    () =>
      (propValueFormat.value == null ? void 0 : propValueFormat.value) ||
      getDefaultValueFormat(mode.value == null ? void 0 : mode.value),
  );
  const parseValueFormat = computed(() =>
    ["timestamp", "Date"].includes(valueFormat.value)
      ? format.value
      : valueFormat.value,
  );
  return {
    format,
    valueFormat,
    parseValueFormat,
  };
}

function usePanelSpan(props) {
  const { mode } = toRefs(props);
  const span = computed(
    () =>
      ({ date: 1, week: 1, year: 10 * 12, quarter: 12, month: 12 })[mode.value],
  );
  const superSpan = computed(() =>
    ["year"].includes(mode.value) ? 10 * 12 : 12,
  );
  return {
    span,
    superSpan,
  };
}

export function useHeaderValue(props) {
  const { mode, value, defaultValue, selectedValue, format, onChange } =
    toRefs(props);
  const computedMode = computed(
    () => (mode.value == null ? void 0 : mode.value) || "date",
  );
  const { span, superSpan } = usePanelSpan(
    reactive({
      mode: computedMode,
    }),
  );
  const isSame = (current, target) => {
    const unit =
      computedMode.value === "date" || computedMode.value === "week"
        ? "M"
        : "y";
    return current.isSame(target, unit);
  };
  const computedValue = computed(() =>
    dayjs(value.value == null ? void 0 : value.value, format.value),
  );
  const computedDefaultValue = computed(() =>
    dayjs(
      defaultValue.value == null ? void 0 : defaultValue.value,
      format.value,
    ),
  );
  const localValue = ref(computedDefaultValue.value || dayjs());
  const headerValue = computed(() => computedValue.value || localValue.value);
  const setLocalValue = (newVal) => {
    if (!newVal) return;
    localValue.value = newVal;
  };
  const setHeaderValue = (newVal, emitChange = true) => {
    let _a;
    if (!newVal) return;
    if (emitChange && !isSame(headerValue.value, newVal)) {
      // eslint-disable-next-line @typescript-eslint/no-unused-expressions
      (_a = onChange.value == null ? void 0 : onChange.value) == null
        ? void 0
        : _a.call(onChange, newVal);
    }
    setLocalValue(newVal);
  };
  if (selectedValue.value == null ? void 0 : selectedValue.value) {
    setLocalValue(selectedValue.value);
  }
  watch(
    () => (selectedValue.value == null ? void 0 : selectedValue.value),
    (newVal) => {
      setHeaderValue(newVal);
    },
  );
  function getDefaultLocalValue() {
    return (
      (selectedValue.value == null ? void 0 : selectedValue.value) ||
      computedDefaultValue.value ||
      dayjs()
    );
  }
  function resetHeaderValue(emitChange = true) {
    const defaultLocalValue = getDefaultLocalValue();
    if (emitChange) {
      setHeaderValue(defaultLocalValue);
    } else {
      setLocalValue(defaultLocalValue);
    }
  }
  const showSingleBtn = computed(() => span.value !== superSpan.value);
  const headerOperations = computed(() => ({
    onSuperPrev: () => {
      setHeaderValue(dayjs(headerValue.value).subtract(superSpan.value, "M"));
    },
    onPrev: showSingleBtn.value
      ? () => {
          setHeaderValue(dayjs(headerValue.value).subtract(span.value, "M"));
        }
      : void 0,
    onNext: showSingleBtn.value
      ? () => {
          setHeaderValue(dayjs(headerValue.value).add(span.value, "M"));
        }
      : void 0,
    onSuperNext: () => {
      setHeaderValue(dayjs(headerValue.value).add(superSpan.value, "M"));
    },
  }));
  return {
    headerValue,
    setHeaderValue,
    headerOperations,
    resetHeaderValue,
    getDefaultLocalValue,
  };
}
